
package com.jf.cloud.payment.manager;

import cn.hutool.core.util.StrUtil;
import com.alipay.api.domain.PayParams;
import com.jf.cloud.api.auth.constant.SysTypeEnum;
import com.jf.cloud.api.feign.SearchOrderFeignClient;
import com.jf.cloud.api.leaf.feign.SegmentFeignClient;
import com.jf.cloud.api.multishop.feign.ShopWalletLogFeignClient;
import com.jf.cloud.common.order.bo.OrderStatusBO;
import com.jf.cloud.api.order.constant.OrderStatus;
import com.jf.cloud.api.order.feign.OrderFeignClient;
import com.jf.cloud.api.order.feign.OrderSettlementFeignClient;
import com.jf.cloud.api.order.vo.OrderSettlementPayVO;
import com.jf.cloud.api.user.feign.UserBalanceLogClient;
import com.jf.cloud.api.user.feign.UserLevelLogClient;
import com.jf.cloud.common.constant.DistributedIdKey;
import com.jf.cloud.common.constant.PayType;
import com.jf.cloud.common.exception.LuckException;
import com.jf.cloud.common.order.bo.PayRefundBO;
import com.jf.cloud.common.product.constant.PreSaleType;
import com.jf.cloud.common.response.ResponseEnum;
import com.jf.cloud.common.response.ServerResponseEntity;
import com.jf.cloud.payment.bo.PayInfoBO;
import com.jf.cloud.payment.bo.PayInfoResultBO;
import com.jf.cloud.payment.dto.RechargePayInfoDTO;
import com.jf.cloud.payment.model.PayInfo;
import com.jf.cloud.payment.service.PayInfoService;
import com.jf.cloud.payment.service.RefundInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author zz
 * @date 2021/5/11
 */
@Component
public class PayNoticeManager {

    @Autowired
    private OrderFeignClient orderFeignClient;

    @Autowired
    private SegmentFeignClient segmentFeignClient;

    @Autowired
    private PayInfoService payInfoService;

    @Autowired
    private RefundInfoService refundInfoService;

    @Autowired
    private UserBalanceLogClient userBalanceLogClient;

    @Autowired
    private ShopWalletLogFeignClient shopWalletLogFeignClient;

    @Autowired
    private UserLevelLogClient userLevelLogClient;

    @Autowired
    private OrderSettlementFeignClient orderSettlementFeignClient;

    @Autowired
    private SearchOrderFeignClient searchOrderFeignClient;


    /**
     * 订单付款回调处理
     * 该方法中调用其他服务如果出现的异常，直接抛出，不要继续执行后续的步骤
     *
     * @param payInfoResultBO
     * @param payInfo
     * @return
     */
    public ResponseEntity<String> noticeOrder(PayInfoResultBO payInfoResultBO, PayInfo payInfo) {

        // 获取订单之前是不是有进行过支付，如果有进行过支付，那么本次支付将直接退款
        String[] orderIdStrArr = payInfo.getOrderIds().split(StrUtil.COMMA);
        List<Long> orderIdList = new ArrayList<>();
        for (String s : orderIdStrArr) {
            orderIdList.add(Long.valueOf(s));
        }

        ServerResponseEntity<List<OrderStatusBO>> ordersStatusResponse = orderFeignClient.getOrdersStatus(orderIdList);

        if (ordersStatusResponse.isFail()) {
            throw new LuckException(ordersStatusResponse.getMsg());
        }
        long actualTotal = 0L;
        List<OrderStatusBO> orderStatusList = ordersStatusResponse.getData();
        for (OrderStatusBO orderStatusBO : orderStatusList) {
            // 如果是定金预售，用定金or尾款钱进行判断
            if (Objects.equals(orderStatusBO.getPreSaleType(), PreSaleType.DEPOSIT.value())) {
                Long preSaleAmount = Objects.equals(orderStatusBO.getStatus(), OrderStatus.UNPAY.value()) ? orderStatusBO.getDepositAmount() : orderStatusBO.getBalanceAmount();
                actualTotal = actualTotal + preSaleAmount;
            } else {
                actualTotal = actualTotal + orderStatusBO.getActualTotal();
            }
            // 有其中一个订单已经支付过了
            if (!Objects.equals(orderStatusBO.getStatus(), OrderStatus.UNPAY.value()) && !Objects.equals(orderStatusBO.getStatus(), OrderStatus.WAIT_BALANCE.value()) && !Objects.equals(orderStatusBO.getStatus(), OrderStatus.CLOSE.value())) {
                ServerResponseEntity<OrderSettlementPayVO> settlementResponse = orderSettlementFeignClient.getPayIdByOrderId(orderStatusBO.getOrderId());
                if (settlementResponse.isFail()) {
                    throw new LuckException(settlementResponse.getMsg());
                }
                OrderSettlementPayVO settlementPayVO = settlementResponse.getData();
                // 相同的支付单号就不判断了
                if (Objects.nonNull(settlementPayVO.getPayId()) && Objects.equals(settlementPayVO.getPayId(), payInfo.getPayId())) {
                    continue;
                }
                ServerResponseEntity<Long> segmentEntity = segmentFeignClient.getSegmentIdWithDateTime(DistributedIdKey.MALL4CLOUD_REFUND, payInfo.getUserId());
                if (segmentEntity.isFail()) {
                    throw new LuckException(segmentEntity.getMsg());
                }
                PayRefundBO payRefundBO = new PayRefundBO();
                payRefundBO.setRefundId(segmentEntity.getData());
                payRefundBO.setRefundAmount(payInfo.getPayAmount());
                payRefundBO.setOrderId(orderStatusBO.getOrderId());
                payRefundBO.setPayId(payInfo.getPayId());
                payRefundBO.setOnlyRefund(1);
                refundInfoService.doRefund(payRefundBO);
                // 标记为退款
                payInfoService.markerRefund(payInfo.getPayId());
                return ResponseEntity.ok(payInfoResultBO.getSuccessString());
            }
        }

        // 如果订单实付金额大于支付金额，则退款
        if (actualTotal > payInfo.getPayAmount()) {
            ServerResponseEntity<Long> segmentEntity = segmentFeignClient.getSegmentIdWithDateTime(DistributedIdKey.MALL4CLOUD_REFUND, payInfo.getUserId());
            PayRefundBO payRefundBO = new PayRefundBO();
            payRefundBO.setRefundId(segmentEntity.getData());
            payRefundBO.setRefundAmount(payInfo.getPayAmount());
            payRefundBO.setPayId(payInfo.getPayId());
            payRefundBO.setOnlyRefund(1);
            refundInfoService.doRefund(payRefundBO);
            // 标记为退款
            payInfoService.markerRefund(payInfo.getPayId());
            return ResponseEntity.ok(payInfoResultBO.getSuccessString());
        }

        // 真正的支付成功
        payInfoService.paySuccess(payInfoResultBO, payInfo, orderIdList);
        return ResponseEntity.ok(payInfoResultBO.getSuccessString());
    }

    public ResponseEntity<String> noticeRecharge(PayInfoResultBO payInfoResultBO, PayInfo payInfo) {

        // 获取订单之前是不是有进行过支付，如果有进行过支付，那么本次支付将直接退款
        Long rechargeLogId = Long.valueOf(payInfo.getOrderIds());

        boolean isShopUser = Objects.equals(payInfo.getSysType(), SysTypeEnum.MULTISHOP.value());
        ServerResponseEntity<Integer> ordersStatusResponse;
        if (isShopUser) {
            ordersStatusResponse = shopWalletLogFeignClient.getIsPay(rechargeLogId);
        } else {
            ordersStatusResponse = userBalanceLogClient.getIsPay(rechargeLogId);
        }

        if (!ordersStatusResponse.isSuccess()) {
            return ResponseEntity.ok(ResponseEnum.EXCEPTION.value());
        }

        Integer isPay = ordersStatusResponse.getData();
        // 有其中一个订单已经支付过了
        if (Objects.equals(isPay, 1)) {
            ServerResponseEntity<Long> segmentId = segmentFeignClient.getSegmentId(DistributedIdKey.MALL4CLOUD_REFUND);
            PayRefundBO payRefundBO = new PayRefundBO();
            payRefundBO.setRefundId(segmentId.getData());
            payRefundBO.setRefundAmount(payInfo.getPayAmount());
            payRefundBO.setOrderId(rechargeLogId);
            payRefundBO.setPayId(payInfoResultBO.getPayId());
            payRefundBO.setOnlyRefund(1);
            refundInfoService.doRefund(payRefundBO);
            // 标记为退款
            payInfoService.markerRefund(payInfo.getPayId());
            return ResponseEntity.ok(payInfoResultBO.getSuccessString());
        }

        // 支付成功
        payInfoService.rechargeSuccess(payInfoResultBO, PayType.instance(payInfo.getPayType()), rechargeLogId, payInfo.getSysType());
        return ResponseEntity.ok(payInfoResultBO.getSuccessString());
    }

    public ResponseEntity<String> noticeBuyVip(PayInfoResultBO payInfoResultBO, PayInfo payInfo) {
        // 获取订单之前是不是有进行过支付，如果有进行过支付，那么本次支付将直接退款
        Long userLevelLogId = Long.valueOf(payInfo.getOrderIds());

        ServerResponseEntity<Integer> ordersStatusResponse = userLevelLogClient.getIsPay(userLevelLogId);

        if (!ordersStatusResponse.isSuccess()) {
            return ResponseEntity.ok(ResponseEnum.EXCEPTION.value());
        }

        Integer isPay = ordersStatusResponse.getData();

        // 有其中一个订单已经支付过了
        if (Objects.equals(isPay, 1)) {
            ServerResponseEntity<Long> segmentId = segmentFeignClient.getSegmentIdWithDateTime(DistributedIdKey.MALL4CLOUD_REFUND, payInfo.getUserId());
            PayRefundBO payRefundBO = new PayRefundBO();
            payRefundBO.setRefundId(segmentId.getData());
            payRefundBO.setRefundAmount(payInfo.getPayAmount());
            payRefundBO.setOrderId(userLevelLogId);
            payRefundBO.setPayId(payInfoResultBO.getPayId());
            payRefundBO.setOnlyRefund(1);
            refundInfoService.doRefund(payRefundBO);
            // 标记为退款
            payInfoService.markerRefund(payInfo.getPayId());
            return ResponseEntity.ok(payInfoResultBO.getSuccessString());
        }

        // 支付成功
        payInfoService.buyVipSuccess(payInfoResultBO, PayType.instance(payInfo.getPayType()), userLevelLogId);
        return ResponseEntity.ok(payInfoResultBO.getSuccessString());
    }
}
